<template>
	<view class="videoContent">
		<view class="videoBox">
			<video class="videoPlayer" :style="{height:wh+'px'}" :src="videoSrc" id="videoPlayer" ref="videoPlayer"
				:enable-danmu.sync="openDanmu" :danmu-btn="isDanmuBtn" :poster='videoImg' :danmu-list="danmu" autoplay
				controls @timeupdate='timeupdatefn' @ended='endedFn' @play="playFn"
				@pause="pauseFn"
				@waiting="waitingFn"
				@error="errorFn">
				<!-- <cover-view class="live-video-btns">
					<cover-image class="course-bg-images" @click="backPlayVideo" :src="videoImg"></cover-image>
					<cover-image  class="play-btn-icons" @click="backPlayVideo" src="/static/img/bfq-icon.png" mode=""></cover-image>
				</cover-view> -->
			</video>
		</view>
		<view class="danmuSendBox" v-if="openDanmu">
			<input type="text" v-model="danmuText" placeholder="发送一条友善的弹幕吧~"><button @click="sendDanmu">发送</button>
		</view>
		<view class="danmuSendBox" v-else :style="{display: isDirectory?'flex':'none'}">
			<view class="item">
				目录
			</view>
		</view>
		<scroll-view scroll-y="true" class="videoSrcList" :style="{height:dirWh + 'px'}" v-if="isDirectory">
			<view v-for="(item,i) in srcList" :key="i" :class="{videoItem:true,select:index == i}"
				@click="onClickItemTochangeIndex(i)">
				<view class="name">
					{{item.name}}
				</view>
				<view class="time">
					{{item.time | timeFormat}}
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	/*
	uniapp 的原生 video 控件支持弹幕系统，所以也顺势做出来了，弹幕的格式为 [{txt:'文字内容',color:'文字颜色',time:'出现的时间段'}]
	srcList 需要传入多个对象，其中 手机端需要额外传入时间总长 [{src:'视频地址',name:'视频名称',time:'视频总长'}]
	
	参数传入
	
	|参数名|默认值|说明|
	|:-|:-|:-|
	|src|''|传入的单个视频|
	|srcList|[]|要传入的多个视频|
	|poster|(默认图片)|视频的封面图片|
	|height|(宽度的16:9)|视频播放区域控件的高度|
	|isDirectory|false|是否展示播放列表|
	|directoryHeight|(自适应)|播放列表高度|
	|isDanmu|false|是否显示弹幕|
	|isDanmuBtn|false|是否显示弹幕按钮|
	|danmuColor|#ffffff|弹幕颜色|
	|danmuList|[]|弹幕数据|
	|videoIndex|0|播放器播放的列表下标|
	
	事件向外
	
	|参数名|参数|说明|
	|:-|:-|:-|
	|sendDanmu|{color,text,time}|用户发送弹幕时触发的事件|
	|timeupdate|event|播放器正在播放时触发的事件|
	|ended|event|音频播放结束时触发的事件|
	
	*/
	let that = null;
	export default {
		name: "smm-video",
		data() {
			return {
				videoCtx: null,
				videoSrc: '',
				wh: 0,
				dirWh: 0,
				openDanmu: this.isDanmu,
				index: this.videoIndex,
				videoImg: this.poster || '',
				videoInfo: '',
				danmu: this.danmuList || [],
				Systeminfo: null,
				timer: null,
				danmuText: '',
				_danmuColor: this.danmuColor,
				videoTime: 0
			};
		},
		props: {
			// 单独的视频地址
			src: {
				type: String,
				default: '#'
			},
			// 多个视频地址
			srcList: {
				type: Array,
				default: () => []
			},
			// 视频播放封面
			poster: {
				typeof: String,
				default: ''
			},
			// 播放器高度
			height: {
				typeof: Number,
				default: 0
			},
			// 是否显示播放列表
			isDirectory: {
				typeof: Boolean,
				default: true
			},
			// 播放列表高度
			directoryHeight: {
				typeof: Number,
				default: 0
			},
			// 是否打开 弹幕
			isDanmu: {
				typeof: Boolean,
				default: false
			},
			// 是否打开 弹幕按钮
			isDanmuBtn: {
				typeof: Boolean,
				default: false
			},
			// 弹幕颜色
			danmuColor: {
				typeof: String,
				default: '#ffffff'
			},
			// 弹幕数组数据
			danmuList: {
				typeof: Array,
				default: () => []
			},
			// 播放列表的下标
			videoIndex: {
				type: Number,
				default: 0
			},
			// 是否自动播放
			autoNext: {
				typeof: Boolean,
				default: true
			}
		},
		watch: {
			// 新播放地址传入
			src(val) {
				this.videoSrc = val;
			},
			srcList: {
				deep: true,
				immediate: true,
				handler(val) {
					this.setTimeToSrcListFn();
				}
			},
			// 播放下标发生改变
			index(val) {
				this.changeVideoIndexToPlay(val);
				this.$emit('changeVideoIndex', {
					id: val,
					data: this.srcList[val]
				})
			},
			// 双向绑定 是否打开弹幕
			openDanmu: {
				deep: true,
				immediate: true,
				handler(val) {
					this.$emit('updata:isDanmu', val);
				}
			},
			// 双向绑定 是否打开弹幕按钮
			isDanmuBtn: {
				deep: true,
				immediate: true,
				handler(val) {
					this.$emit('updata:isDanmuBtn', val);
				}
			}
		},
		created() {
			that = this;

			this.Systeminfo = uni.getSystemInfoSync();

			// 初始化高度
			this.SetHeightParament();
			console.log(this.wh, this.dirWh);


			// 获取 video 对象
			this.videoCtx = uni.createVideoContext("videoPlayer", this);

			// 等待载入
			this.timer = setInterval(() => {
				// 单个视频
				if (this.src !== '#') {
					console.log('导入单个视频信息');
					this.videoSrc = this.src;
					clearInterval(this.timer);
				}
				// 多个视频对象
				if (this.srcList.length) {
					console.log('导入多个视频信息');
					console.log(this.index);
					this.videoSrc = this.srcList.length ? this.srcList[this.index].src : '#';
					clearInterval(this.timer);
				}
			}, 500);
		},
		methods: {
			backPlayVideo:function(){
				console.log('sdsdsdsdsd')
				this.$emit('backPlayVideo');
			},
			// 设置组件高度
			SetHeightParament() {

				// 是否设置播放器高度
				if (!this.height) {
					this.wh = this.Systeminfo?.windowWidth / 16 * 9 || 340;

					// 是否设置的播放目录的高度
					if (!this.directoryHeight) {
						this.dirWh = this.Systeminfo?.windowHeight - this.wh - (this.isDanmu ? 50 : 0);
					} else {
						this.dirWh = this.directoryHeight;
					}

				} else {

					this.wh = this.height;

					// 是否设置的播放目录的高度
					if (!this.directoryHeight) {
						this.dirWh = this.Systeminfo?.windowHeight - this.wh - (this.isDanmu ? 50 : 0);
					} else {
						this.dirWh = this.directoryHeight;
					}
				}
			},
			// 改变播放列表的下标
			changeVideoIndexToPlay(index) {
				this.videoSrc = this.srcList.length ? this.srcList[index]?.src : '#';
				this.videoInfo = this.srcList.length ? this.srcList[index]?.name : '';
			},
			onClickItemTochangeIndex(index) {
				this.index = index;
				this.changeVideoIndexToPlay(index);
			},
			// 发送弹幕 处理函数
			sendDanmu() {
				if (!this.danmuText) return

				let danmuData = {
					text: that.danmuText,
					color: that.danmuColor,
					time: this.videoTime
				};

				this.videoCtx.sendDanmu(danmuData);

				this.$emit('sendDanmu', danmuData);

				this.danmuText = '';
			},
			// 播放时间发生改变 处理函数
			timeupdatefn(e) {
				this.videoTime = Math.floor(e.detail.currentTime);
				this.$emit('timeupdate', e);
			},
			setTimeToSrcListFn() {
				const type = this.srcList.every(item => item.time);
				if (!type) {

					this.srcList.forEach(async item => {
						console.log('获取时长');

						// 移动端不支持该方法
						const time = await this.getVideoDuration(item.src);
						console.log('当前时间' + time);
						return item.time = Math.floor(time);
					});
				}
			},
			// 获取播放列表的 播放视频的时长
			getVideoDuration(url) {
				return new Promise((resolve, reject) => {

					let video = document.createElement('video');
					console.log('对象:' + video);
					video.src = url;
					video.onloadedmetadata = () => {
						resolve(video.duration);
					};
					video.onerror = (err) => {
						reject(err);
					};
				});
			},
			// 上个视频
			playUp() {
				if (this.srcList.length) {
					this.index != 0 ? this.index = this.index - 1 : this.index =
						this.srcList.length - 1;
					this.changeVideoIndexToPlay(this.index);
				}
			},
			// 下个视频
			playDown() {
				if (this.srcList.length) {
					this.index < this.srcList.length - 1 ? this.index = this.index + 1 :
						this.index = 0;
					this.changeVideoIndexToPlay(this.index);
				}
			},
			endedFn(e) {
				const index = this.index < this.srcList.length ? this.index + 1 : 0;
				this.playDown();
				this.$emit('ended', e);
			},
			// 播放
			playFn(e) {
				this.$emit('play', e);
			},
			//暂停
			pauseFn(e) {
				this.$emit('pause', e);
			},
			//获取视频出现缓冲时间
			waitingFn(e) {
				this.$emit('waiting', e);
			},
			// 错误
			errorFn(e) {
				this.$emit('error', e);
			}
		},
		filters: {
			timeFormat(value) {
				let result = typeof value === "string" ? parseFloat(value) : value;
				if (isNaN(result))
					return "";
				let h = Math.floor(result / 3600) < 10 ?
					"0" + Math.floor(result / 3600) :
					Math.floor(result / 3600);
				let m = Math.floor((result / 60) % 60) < 10 ?
					"0" + Math.floor((result / 60) % 60) :
					Math.floor((result / 60) % 60) + h * 60;
				let s = Math.floor(result % 60) < 10 ?
					"0" + Math.floor(result % 60) :
					Math.floor(result % 60);

				return h == '00' ? `${m}:${s}` : `${h}:${m}:${s}`;
			}
		}
	}
</script>

<style lang="scss" scoped>
	.videoContent {
		width: 100%;
        position: relative;
		.videoBox {
			.videoPlayer {
				width: 100%;
			}
			.live-video-btns{
				 width: 100%;
				 height: 28vh;
				 object-fit: cover; /* 确保视频撑满父容器 */
				 // position: absolute;
				 // top: 0;
				 // right: 0;
				 // z-index: 11111;
				 text-align: center;
				 color: #fff;
				 background-color: rgba(0,0,0,0.3);
				 .course-bg-images{
					position: absolute;
					top: 0;
					right: 0;
					width: 100%;
					height: 28vh;
					object-fit: contain
				 }
			}
			.play-btn-icons{
				  width: 120rpx;
				  height: 120rpx;
				  transform: translate(0px, 150rpx);
				  margin:auto;
				  opacity: 0.6;
			}
		}

		.danmuSendBox {
			height: 50px;
			width: 100%;
			box-sizing: border-box;
			display: flex;
			padding: 0 10px;
			box-shadow: 0px 3px 3px rgba(0, 0, 0, .2);
			justify-content: space-between;
			align-items: center;
			overflow: hidden;

			input {
				box-sizing: border-box;
				flex: 3;
				height: 33px;
				border-radius: 8px;
				border: 1px solid #007bff !important;
				padding: 5px 15px;
				font-size: 14px;
			}

			button {
				flex: 1;
				height: 34px;
				display: flex;
				margin-left: 10px;
				font-size: 14px;
				justify-content: center;
				align-items: center;
				color: #fff;
				border: 0;
				background-color: #007bff;
			}

			.item {
				position: relative;
				font-size: 16px;
				margin-left: 20px;

				&:before {
					content: '';
					display: block;
					position: absolute;
					top: 0;
					left: -10px;
					width: 3px;
					height: 100%;
					background-color: #007bff;
				}
			}
		}

		.videoSrcList {
			width: 100%;

			.videoItem {
				height: 48px;
				display: flex;
				justify-content: space-between;
				align-items: center;
				padding: 0 15px;
				font-size: 14px;
				color: rgba(0, 0, 0, .7);

				&.select {
					color: #007bff;
					font-weight: 800;
				}
			}
		}
	}
</style>